﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using PMisuseAn.io;
using PMisuseAn.util;
using System.Collections;

namespace PMisuseAn.behaviour.model
{
    public class  MisuseAnalyser
    {
        List<Policy> allPolicies;
        List<Policy> policyChecklist;

        PolicyStatementAnalyser statAnalyser;
        PolicyStatementAnalyser aggStatAnalyser;

        public List<List<Threat>> threats;
        public List<Threat> cachePotentialThreats;
        
        List<Threat> allTimeCacheThreatCheckList;

        public bool misuseFound = false;
        public bool potentialMisuseFound = false;

        bool allTimeCall = false;
        public MisuseAnalyser()
        {
            threats = new List<List<Threat>>();
            cachePotentialThreats = new List<Threat>();
            allTimeCacheThreatCheckList = new List<Threat>();

            allPolicies = MisUseAnObjectsDB.loadAllPolicyStatementsFull(MainWindow.clusterName);
            statAnalyser = new PolicyStatementAnalyser();
            aggStatAnalyser = new PolicyStatementAnalyser();
        }
        
        public void IdentifyMisuse(Agent sourceAgent, Agent sendAgent, Agent receiveAgent,
            Agent subjectAgent, State message_s, Transition message_t, List<Object> parameterisedContextInstances_x,
            Dictionary<Dictionary<Agent, Agent>, ListDictionary> sendReceiveContextAgent, Context contextInstance)
        {

            if (sourceAgent.agentName.Equals(sendAgent.agentName) || sourceAgent.agentName.Equals(subjectAgent.agentName) || sourceAgent.agentName.Equals(receiveAgent.agentName))
            //if (sourceAgent.agentName.Equals(sendAgent.agentName) || sourceAgent.agentName.Equals(subjectAgent.agentName))
            {
                List<Threat> newThreats;
                newThreats = new List<Threat>();

                pruneThroughAllTimeHenceforthCacheThreat(parameterisedContextInstances_x, contextInstance);
                pruneThroughCachePotentialThreats(parameterisedContextInstances_x, contextInstance);

                allTimeCall = false;

                if (sourceAgent.agentName.Equals(sendAgent.agentName) || sourceAgent.agentName.Equals(subjectAgent.agentName))
                {
                    policyChecklist = new List<Policy>();

                    genPolicyChecklist(message_s, message_t, subjectAgent, policyChecklist);

                    foreach (Policy policy in policyChecklist)
                    {
                        if (!policy.statement.Equals("DO[NILL]"))
                        {
                            statAnalyser.ifThenUnlessContentTokenisation(policy.statement);
                            bool applicableIFPolicySegment = true;
                            //bool applicableIFPolicySegment = ApplicableIfTest.applicableIfAnalysis(sendAgent,
                            //                                receiveAgent, subjectAgent, message_s, message_t,
                            //                                parameterisedContextInstances_x, statAnalyser, contextInstance);

                            string thenTemporalType = getThenTemporalType(policy);
                            bool thenSatisfied = false;
                            bool unlessSatisfied = false;

                            if (applicableIFPolicySegment == true)
                            {
                                string unlessTemporalType = null;

                                switch (thenTemporalType)
                                {
                                    case "LAST-TIME":
                                        thenSatisfied = SatisfiedLastTimeTest.satisfiedAnalysis(sendAgent, receiveAgent,
                                                                           subjectAgent, statAnalyser.tokenisedThenContent, contextInstance);
                                        break;
                                    case "PREVIOUSLY":
                                        thenSatisfied = SatisfiedPreviouslyTest.satisfiedAnalysis(sendAgent, receiveAgent,
                                                                           subjectAgent, statAnalyser.tokenisedThenContent, contextInstance);
                                        break;
                                    case "EVENTUALLY":
                                        break;
                                    case "HENCEFORTH":
                                        thenSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(sendAgent, receiveAgent,
                                                                       subjectAgent, message_s, message_t, parameterisedContextInstances_x,
                                                                       statAnalyser.tokenisedUnlessContent, contextInstance);
                                        break;
                                    case "NEXT-TIME":
                                        break;
                                    case "ALL-TIME":
                                        //DO satisfy previously test and add to allTimeCacheThreatChecks
                                        thenSatisfied = SatisfiedAllTimeTest.satisfiedAnalysis(sendAgent, receiveAgent,
                                                                           subjectAgent, statAnalyser.tokenisedThenContent, contextInstance);
                                        break;
                                }

                                if (thenSatisfied == false)
                                {
                                    unlessTemporalType = getUnlessTemporalType(policy);
                                    switch (unlessTemporalType)
                                    {
                                        case "LAST-TIME":
                                            unlessSatisfied = SatisfiedLastTimeTest.satisfiedAnalysis(sendAgent, receiveAgent,
                                                                            subjectAgent, statAnalyser.tokenisedUnlessContent, contextInstance);
                                            break;
                                        case "PREVIOUSLY":
                                            unlessSatisfied = SatisfiedPreviouslyTest.satisfiedAnalysis(sendAgent, receiveAgent,
                                                                           subjectAgent, statAnalyser.tokenisedUnlessContent, contextInstance);
                                            break;
                                        case "EVENTUALLY":
                                            break;
                                        case "HENCEFORTH":
                                            thenSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(sendAgent, receiveAgent,
                                                                           subjectAgent, message_s, message_t, parameterisedContextInstances_x,
                                                                           statAnalyser.tokenisedUnlessContent, contextInstance);
                                            break;
                                        case "NEXT-TIME":
                                            break;
                                        case "ALL-TIME":
                                            //DO satisfy previously test and add to allTimeCacheThreatChecks
                                            unlessSatisfied = SatisfiedAllTimeTest.satisfiedAnalysis(sendAgent, receiveAgent,
                                                                         subjectAgent, statAnalyser.tokenisedUnlessContent, contextInstance);
                                            break;
                                    }
                                }

                                if (thenTemporalType.Equals("LAST-TIME")
                                   || thenTemporalType.Equals("PREVIOUSLY")
                                    || thenTemporalType.Equals("ALL-TIME")
                                    || thenTemporalType.Equals("HENCEFORTH"))
                                {
                                    if (thenSatisfied == false && unlessSatisfied == false)
                                    {
                                        Threat threat = new Threat();
                                        threat.comments = "AUTHORISATION-FAILURE";
                                        threat.subjectAgent = subjectAgent;
                                        threat.sendAgent = sendAgent;
                                        threat.recieveAgent = receiveAgent;
                                        threat.violatingParameterisedContextInstances = parameterisedContextInstances_x;
                                        threat.violatedPolicy = policy;
                                        threat.timestamp = DateTime.Now;
                                        if (message_s != null)
                                        {
                                            threat.message_s = message_s;
                                        }
                                        else if (message_t != null)
                                        {
                                            threat.message_t = message_t;
                                        }

                                        threat.rationalle = "[Transmission policy will be violated by this context]";
                                        threat.threatType = Threat.ThreatType.currentThreat;

                                        newThreats.Add(threat);
                                        misuseFound = true;
                                    }
                                }

                                if ((thenTemporalType.Equals("ALL-TIME") || thenTemporalType.Equals("HENCEFORTH"))
                                   && (thenSatisfied == true || unlessSatisfied == true))
                                {
                                    Threat threat = new Threat();
                                    threat.subjectAgent = subjectAgent;
                                    threat.sendAgent = sendAgent;
                                    threat.recieveAgent = receiveAgent;
                                    threat.violatingParameterisedContextInstances = parameterisedContextInstances_x;
                                    threat.timestamp = DateTime.Now;
                                    threat.violatedPolicy = policy;
                                    if (message_s != null)
                                    {
                                        threat.message_s = message_s;
                                    }
                                    else if (message_t != null)
                                    {
                                        threat.message_t = message_t;
                                    }
                                    allTimeCacheThreatCheckList.Add(threat);
                                }
                                if (thenTemporalType.Equals("EVENTUALLY")
                                        || thenTemporalType.Equals("NEXT-TIME"))
                                {
                                    Threat threat = new Threat();
                                    threat.comments = "UNFULFILLED-OBLIGATION";

                                    threat.subjectAgent = subjectAgent;
                                    threat.sendAgent = sendAgent;
                                    threat.recieveAgent = receiveAgent;
                                    threat.violatingParameterisedContextInstances = parameterisedContextInstances_x;
                                    threat.timestamp = DateTime.Now;
                                    threat.violatedPolicy = policy;
                                    if (message_s != null)
                                    {
                                        threat.message_s = message_s;
                                    }
                                    else if (message_t != null)
                                    {
                                        threat.message_t = message_t;
                                    }

                                    threat.rationalle = "[Transmission policy not yet satisfied]";
                                    threat.threatType = Threat.ThreatType.futureThreat;

                                    cachePotentialThreats.Add(threat);

                                    potentialMisuseFound = true;
                                }
                            }
                        }
                    }
                    if (newThreats.Count > 0)
                    {
                        threats.Add(newThreats);
                    }
                    //check for possible misuse based on data aggregation
                    EmulationEnvironmentWindow.aggregationMisuseAnalyser.checkAggregationMisuse(sourceAgent, sendAgent, receiveAgent,
                                            subjectAgent, message_s, message_t, parameterisedContextInstances_x, statAnalyser, sendReceiveContextAgent, contextInstance, this);
            
                }
            }
        }
        
        private void pruneThroughAllTimeHenceforthCacheThreat(List<Object> parameterisedContextInstances_z, Context contextInstance)
        {

            List<Threat> newAllTimeCacheThreatCheckList = new List<Threat>();
            foreach (Threat threat in allTimeCacheThreatCheckList)
            {
                //    //correlate parameterised context with attributes in threat message_s/t
                //    if (threat.message_s != null)
                //    {
                //        foreach (Attribute att in threat.message_s.activeAction.parameterisedOperationalAttributes)
                //        {
                //            foreach (Object obj in parameterisedContextInstances_z)
                //            {
                //                Attribute att_p = obj as Attribute;
                //                if (att_p != null)
                //                {
                //                    if (att.name.Equals(att_p.name))
                //                    {
                //                        att_p.activeDomain = att.activeDomain;
                //                        parameterisedContextInstances_z.Remove(att_p);
                //                        parameterisedContextInstances_z.Add(att);
                //                        break;
                //                    }
                //                }
                //            }
                //        }
                //    }
                //    else if (threat.message_t != null)
                //    {
                //        foreach (Attribute att in threat.message_t.activeEvent.parameterisedOperationalAttributes)
                //        {
                //            foreach (Object obj in parameterisedContextInstances_z)
                //            {
                //                Attribute att_p = obj as Attribute;
                //                if (att_p != null)
                //                {
                //                    if (att.name.Equals(att_p.name))
                //                    {
                //                        att_p.activeDomain = att.activeDomain;
                //                        parameterisedContextInstances_z.Remove(att_p);
                //                        parameterisedContextInstances_z.Add(att);
                //                        break;
                //                    }
                //                }
                //            }
                //        }
                //    }
                //////
                statAnalyser.ifThenUnlessContentTokenisation(threat.violatedPolicy.statement);
                bool applicableIFPolicySegment = true;
                //bool applicableIFPolicySegment = ApplicableIfTest.applicableIfAnalysis(threat.sendAgent,
                //                                   threat.recieveAgent, threat.subjectAgent, threat.message_s, threat.message_t,
                //                                   parameterisedContextInstances_z, statAnalyser, contextInstance);

                if (applicableIFPolicySegment == true)
                {
                    string thenTemporalType = getThenTemporalType(threat.violatedPolicy);
                    string unlessTemporalType = null;
                    bool thenSatisfied = false;

                    switch (thenTemporalType)
                    {
                        case "ALL-TIME":
                            //DO satisfy previously test and add to allTimeCacheThreatChecks
                            thenSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_z,
                                                               statAnalyser.tokenisedThenContent, contextInstance);
                            break;
                        case "HENCEFORTH":
                            //DO satisfy previously test and add to allTimeCacheThreatChecks
                            thenSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_z,
                                                               statAnalyser.tokenisedThenContent, contextInstance);
                            break;
                    }

                    bool unlessSatisfied = false;
                    if (thenSatisfied == false)
                    {
                        unlessTemporalType = getUnlessTemporalType(threat.violatedPolicy);
                        switch (unlessTemporalType)
                        {
                            case "LAST-TIME":
                                unlessSatisfied = SatisfiedLastTimeTest.satisfiedAnalysis(threat.sendAgent, threat.recieveAgent,
                                                                threat.subjectAgent, statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                            case "PREVIOUSLY":
                                unlessSatisfied = SatisfiedPreviouslyTest.satisfiedAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                            case "EVENTUALLY":
                                break;
                            case "HENCEFORTH":
                                unlessSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_z,
                                                               statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                            case "NEXT-TIME":
                                break;
                            case "ALL-TIME":
                                //DO satisfy previously test and add to allTimeCacheThreatChecks
                                unlessSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_z,
                                                               statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                        }
                    }
                    if (thenTemporalType.Equals("ALL-TIME") || thenTemporalType.Equals("HENCEFORTH"))
                    {
                        if (thenSatisfied == false && unlessSatisfied == false)
                        {
                            Threat threat_at = new Threat();
                            //threat_at.comments = thenTemporalType + "-CHECK";
                            threat_at.comments = "OBLIGATION-FAILURE";
                            threat_at.subjectAgent = threat.subjectAgent;
                            threat_at.sendAgent = threat.sendAgent;
                            threat_at.recieveAgent = threat.recieveAgent;
                            threat.violatingParameterisedContextInstances = parameterisedContextInstances_z;
                            threat.timestamp = DateTime.Now;
                            threat_at.violatedPolicy = threat.violatedPolicy;
                            if (threat.message_s != null)
                            {
                                threat_at.message_s = threat.message_s;
                            }
                            else if (threat.message_t != null)
                            {
                                threat_at.message_t = threat.message_t;
                            }

                            threat.rationalle = "[This context invalidates an ALL-TIME/HENCEFORTH transmission policy]";
                            threat.threatType = Threat.ThreatType.currentThreat;

                            newAllTimeCacheThreatCheckList.Add(threat);

                            misuseFound = true;
                        }
                    }
                }
            }
            if (newAllTimeCacheThreatCheckList.Count > 0)
            {
                threats.Add(newAllTimeCacheThreatCheckList);
                allTimeCall = true;
            }

        }

        private void pruneThroughCachePotentialThreats(List<Object> parameterisedContextInstances_k, Context contextInstance)
        {
            List<Threat> cachePrune = new List<Threat>();
            List<Threat> newThreats = new List<Threat>();

            foreach (Threat threat in cachePotentialThreats)
            {
                ////correlate parameterised context with attributes in threat message_s/t
                //if (threat.message_s != null)
                //{
                //    foreach (Attribute att in threat.message_s.activeAction.parameterisedOperationalAttributes)
                //    {
                //        foreach (Object obj in parameterisedContextInstances_k)
                //        {
                //            Attribute att_p = obj as Attribute;
                //            if (att_p != null)
                //            {
                //                if (att.name.Equals(att_p.name))
                //                {
                //                    att_p.activeDomain = att.activeDomain;
                //                    parameterisedContextInstances_k.Remove(att_p);
                //                    parameterisedContextInstances_k.Add(att);
                //                    break;
                //                }
                //            }
                //        }
                //    }
                //}
                //else if (threat.message_t != null)
                //{
                //    foreach (Attribute att in threat.message_t.activeEvent.parameterisedOperationalAttributes)
                //    {
                //        foreach (Object obj in parameterisedContextInstances_k)
                //        {
                //            Attribute att_p = obj as Attribute;
                //            if (att_p != null)
                //            {
                //                if (att.name.Equals(att_p.name))
                //                {
                //                    att_p.activeDomain = att.activeDomain;
                //                    parameterisedContextInstances_k.Remove(att_p);
                //                    parameterisedContextInstances_k.Add(att);
                //                    break;
                //                }
                //            }
                //        }
                //    }
                //}
                ////////

                statAnalyser.ifThenUnlessContentTokenisation(threat.violatedPolicy.statement);
                bool applicableIFPolicySegment = true;
                //bool applicableIFPolicySegment = ApplicableIfTest.applicableIfAnalysis(threat.sendAgent,
                //                                   threat.recieveAgent, threat.subjectAgent, threat.message_s, threat.message_t,
                //                                   parameterisedContextInstances_k, statAnalyser, contextInstance);

                if (applicableIFPolicySegment == true)
                {
                    string thenTemporalType = getThenTemporalType(threat.violatedPolicy);
                    string unlessTemporalType = null;
                    bool thenSatisfied = false;

                    switch (thenTemporalType)
                    {
                        case "EVENTUALLY":
                            thenSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_k,
                                                               statAnalyser.tokenisedThenContent, contextInstance);
                            break;
                        case "NEXT-TIME":
                            thenSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_k,
                                                               statAnalyser.tokenisedThenContent, contextInstance);
                            break;
                    }

                    bool unlessSatisfied = false;
                    if (thenSatisfied == false)
                    {
                        unlessTemporalType = getUnlessTemporalType(threat.violatedPolicy);
                        switch (unlessTemporalType)
                        {
                            case "LAST-TIME":
                                unlessSatisfied = SatisfiedLastTimeTest.satisfiedAnalysis(threat.sendAgent, threat.recieveAgent,
                                                                threat.subjectAgent, statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                            case "PREVIOUSLY":
                                unlessSatisfied = SatisfiedPreviouslyTest.satisfiedAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                            case "EVENTUALLY":
                                thenSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_k,
                                                               statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                            case "NEXT-TIME":
                                thenSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_k,
                                                               statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                            case "HENCEFORTH":
                                thenSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_k,
                                                               statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                            case "ALL-TIME":
                                //DO satisfy previously test and add to allTimeCacheThreatChecks
                                unlessSatisfied = NextSatisfactionTest.nextSatisfactionAnalysis(threat.sendAgent, threat.recieveAgent,
                                                               threat.subjectAgent, threat.message_s, threat.message_t, parameterisedContextInstances_k,
                                                               statAnalyser.tokenisedUnlessContent, contextInstance);
                                break;
                        }
                    }
                    if (thenTemporalType.Equals("EVENTUALLY"))
                    {
                        if (thenSatisfied == true || unlessSatisfied == true)
                        {
                            cachePrune.Add(threat);
                        }
                    }
                    if (thenTemporalType.Equals("NEXT-TIME"))
                    {
                        if (thenSatisfied == false && unlessSatisfied == false)
                        {
                            Threat threat_at = new Threat();
                            //threat_at.comments = thenTemporalType + "CHECK";
                            threat_at.comments = "OBLIGATION-FAILURE";
                            threat_at.subjectAgent = threat.subjectAgent;
                            threat_at.sendAgent = threat.sendAgent;
                            threat_at.recieveAgent = threat.recieveAgent;
                            threat.violatingParameterisedContextInstances = parameterisedContextInstances_k;
                            threat.timestamp = DateTime.Now;
                            threat_at.violatedPolicy = threat.violatedPolicy;
                            if (threat.message_s != null)
                            {
                                threat_at.message_s = threat.message_s;
                            }
                            else if (threat.message_t != null)
                            {
                                threat_at.message_t = threat.message_t;
                            }

                            threat_at.rationalle = "[This context fails a NEXT-TIME transmission policy]";
                            threat.threatType = Threat.ThreatType.currentThreat;

                            newThreats.Add(threat);

                            misuseFound = true;
                        }
                        else
                        {
                            cachePrune.Add(threat);
                        }
                    }
                }
            }
            if (newThreats.Count > 0)
            {
                threats.Add(newThreats);
            }
            foreach (Threat threat in cachePrune)
            {
                foreach(Threat threat1 in cachePotentialThreats)
                {
                    if (threat.timestamp == threat1.timestamp)
                    {
                        cachePotentialThreats.Remove(threat1);
                        break;
                    }
                }
            }
        }

        public string getUnlessTemporalType(Policy policy)
        {
            string unlesstemporalType = null;

            if (!policy.statement.Equals("DO[NILL]"))
            {
                statAnalyser.ifThenUnlessContentTokenisation(policy.statement);
                foreach (DictionaryEntry policyItem in statAnalyser.tokenisedUnlessContent)
                {
                    int pol_id = (int)policyItem.Key;

                    Dictionary<string, string> word_m = (Dictionary<string, string>)policyItem.Value;

                    foreach (KeyValuePair<string, string> pair in word_m)
                    {
                        string type = pair.Key;
                        string word = pair.Value;
                        if (type.Equals("temporalconstraint"))
                        {
                            unlesstemporalType = word;
                            break;
                        }
                    }
                }
            }
            return unlesstemporalType;
        }

        public string getThenTemporalType(Policy policy)
        {
            string thenTemporalType = null;

            if (!policy.statement.Equals("DO[NILL]"))
            {
                statAnalyser.ifThenUnlessContentTokenisation(policy.statement);
                foreach (DictionaryEntry policyItem in statAnalyser.tokenisedThenContent)
                {
                    int pol_id = (int)policyItem.Key;

                    Dictionary<string, string> word_m = (Dictionary<string, string>)policyItem.Value;

                    foreach (KeyValuePair<string, string> pair in word_m)
                    {
                        string type = pair.Key;
                        string word = pair.Value;
                        if (type.Equals("temporalconstraint"))
                        {
                            thenTemporalType = word;
                            break;
                        }
                    }
                }
            }
            return thenTemporalType;
        }

        public string getThenTemporalType(string aggStatement)
        {
            string thenTemporalType = null;

            if (!aggStatement.Equals("DO[NILL]"))
            {
                statAnalyser.ifThenUnlessContentTokenisation(aggStatement);
                foreach (DictionaryEntry policyItem in statAnalyser.tokenisedThenContent)
                {
                    int pol_id = (int)policyItem.Key;

                    Dictionary<string, string> word_m = (Dictionary<string, string>)policyItem.Value;

                    foreach (KeyValuePair<string, string> pair in word_m)
                    {
                        string type = pair.Key;
                        string word = pair.Value;
                        if (type.Equals("temporalconstraint"))
                        {
                            thenTemporalType = word;
                            break;
                        }
                    }
                }
            }
            return thenTemporalType;
        }

        public void genPolicyChecklist(Attribute attribute, List<Policy> policyChecklist)
        {
            PolicyStatementAnalyser psa = new PolicyStatementAnalyser();

            foreach (Policy policy in allPolicies)
            {
                psa.ifThenUnlessTokenisation(policy.statement);
                Attribute att = psa.getIfAttribute();
                if (att != null && att.name.Equals(attribute.name))
                {
                    policyChecklist.Add(policy);
                }
            }
        }

        public void genPolicyChecklist(State message_s, Transition message_t, Agent sourceAgent, List<Policy> policyChecklist)
        {
            //get necessary policies from associated state or transition
            // if state (get all policies for indirected transitions)
            if (message_s != null)
            {
                foreach (Transition transition in sourceAgent.assignedMachine.transitions)
                {
                    if (transition.isCallable == false)
                    {
                        continue;
                    }
                    if (transition.endState.Equals(message_s.name))
                    {
                        Event activeEvent = transition.activeEvent;
                        PolicyStatementAnalyser psa = new PolicyStatementAnalyser();

                        foreach(string opAttribute in activeEvent.operationalAttributes_)
                        {
                            foreach (Policy policy in allPolicies)
                            {
                                psa.ifThenUnlessTokenisation(policy.statement);
                                Attribute att = psa.getIfAttribute();
                                if (att != null && att.name.Equals(opAttribute))
                                {
                                    policyChecklist.Add(policy);
                                }
                            }
                        }
                        
                        //foreach (string policyID in transition.policyIDs)
                        //{
                        //    foreach (Policy policy in allPolicies)
                        //    {
                        //        if (policy.id.Equals(policyID))
                        //        {
                        //            policyChecklist.Add(policy);
                        //        }
                        //    }
                        //}
                    }
                }
            }
            else if (message_t != null && (message_t.isCallable == true))
            {
                Event activeEvent = message_t.activeEvent;
                PolicyStatementAnalyser psa = new PolicyStatementAnalyser();

                foreach (string opAttribute in activeEvent.operationalAttributes_)
                {
                    foreach (Policy policy in allPolicies)
                    {
                        psa.ifThenUnlessTokenisation(policy.statement);
                        Attribute att = psa.getIfAttribute();
                        if (att != null && att.name.Equals(opAttribute))
                        {
                            policyChecklist.Add(policy);
                        }
                    }
                }

                //foreach (string policyID in message_t.policyIDs)
                //{
                //    foreach (Policy policy in allPolicies)
                //    {
                //        if (policy.id.Equals(policyID))
                //        {
                //            policyChecklist.Add(policy);
                //        }
                //    }
                //}
            }

        }
    }
}
